// 08_packages_and_modules.rs
// Rust 包和模块教程

// 1. 创建模块
mod front_of_house {
    // 2. 模块可以嵌套
    pub mod hosting {
        pub fn add_to_waitlist() {
            println!("添加到等待列表");
        }
        
        fn seat_at_table() {
            println!("安排座位");
        }
    }
    
    pub mod serving {
        fn take_order() {
            println!("接受订单");
        }
        
        pub fn serve_order() {
            println!("上菜");
        }
        
        fn take_payment() {
            println!("收款");
        }
    }
}

// 3. 使用 pub 关键字公开结构体和枚举
pub struct Breakfast {
    pub toast: String,
    seasonal_fruit: String,
}

impl Breakfast {
    pub fn summer(toast: &str) -> Breakfast {
        Breakfast {
            toast: String::from(toast),
            seasonal_fruit: String::from("桃子"),
        }
    }
}

// 4. 公开枚举会使所有成员都公开
pub enum Appetizer {
    Soup,
    Salad,
}

// 5. 使用 use 关键字引入模块
use crate::front_of_house::hosting;
// 也可以使用相对路径
// use front_of_house::hosting;

// 6. 使用 super 引用父模块
mod back_of_house {
    fn fix_incorrect_order() {
        cook_order();
        super::front_of_house::serving::serve_order();
    }
    
    fn cook_order() {
        println!("烹饪订单");
    }
    
    // 7. 公开结构体
    pub struct Breakfast {
        pub toast: String,
        seasonal_fruit: String,
    }
    
    impl Breakfast {
        pub fn summer(toast: &str) -> Breakfast {
            Breakfast {
                toast: String::from(toast),
                seasonal_fruit: String::from("桃子"),
            }
        }
    }
    
    // 8. 公开枚举
    pub enum Appetizer {
        Soup,
        Salad,
    }
}

fn main() {
    // 9. 调用模块中的函数
    front_of_house::hosting::add_to_waitlist();
    
    // 10. 使用 use 引入的模块
    hosting::add_to_waitlist();
    
    // 11. 使用公开的结构体
    let mut meal = back_of_house::Breakfast::summer("黑麦");
    println!("我想要 {} 吐司", meal.toast);
    
    meal.toast = String::from("全麦");
    println!("我实际上想要 {} 吐司", meal.toast);
    
    // meal.seasonal_fruit = String::from("蓝莓");  // 这行会报错，因为 seasonal_fruit 是私有的
    
    // 12. 使用公开的枚举
    let order1 = back_of_house::Appetizer::Soup;
    let order2 = back_of_house::Appetizer::Salad;
    
    // 13. 使用 use 简化路径
    use std::collections::HashMap;
    let mut map = HashMap::new();
    map.insert(1, 2);
    
    // 14. 使用 as 关键字提供新名称
    use std::fmt::Result as FmtResult;
    use std::io::Result as IoResult;
    
    // 15. 使用 pub use 重新导出
    mod front_of_house_reexport {
        pub mod hosting {
            pub fn add_to_waitlist() {}
        }
    }
    
    pub use front_of_house_reexport::hosting;
    
    // 16. 嵌套路径消除重复
    use std::collections::{HashMap as Map, HashSet};
    
    // 17. 全局引入
    use std::collections::*;
    
    // 18. 模块文件结构示例
    // 对于一个真实的项目，模块通常会组织成以下结构：
    //
    // src/
    // ├── main.rs
    // ├── lib.rs
    // └── front_of_house/
    //     ├── mod.rs
    //     ├── hosting.rs
    //     └── serving.rs
    //
    // 或者：
    //
    // src/
    // ├── main.rs
    // ├── lib.rs
    // ├── front_of_house.rs
    // ├── front_of_house/
    //     ├── hosting.rs
    //     └── serving.rs
}

// 19. 将模块分离到不同文件
// 当模块变得很大时，可以将其分离到单独的文件中
// 例如，front_of_house 模块可以放在 front_of_house.rs 文件中
// 或者放在 front_of_house/mod.rs 文件中（如果它有子模块）